/**
 * 常用类型检测
 *  typeof
 *  instanceof
 *  constructor
 *  Object.prototype.toString.call
 *  是否为数组：Array.isArray()
 *  是否为空: isNaN()
*/

/**
 * typeof instanceof区别
 */

var { log } = console;

// 1. typeof返回的是对应数据类型的检测
// ****** 计算机typeof返回的数据类型是依据数据转码后的机器码的·后三位·进行判断的(js设计中的bug): 当机器码后三位为000时, 返回object
// ****** typeof检测·引用类型·时，object在内部分为object以及function；
//        且在object内部定义了一个call方法，在检测时会首先判断引用关系上是否使用了call方法；如果使用了call方法则返回function，反之为object
log(typeof (123)); // Number
log(typeof (true)); // boolean
log(typeof ("123")); // string

log(typeof (undefined)); // undefined
log(typeof (null)); // object? 为什么不是null: null的机器码为00000...000

log(typeof ([])); // object
log(typeof (new Date())); // object
log(typeof ({})); // object

log(typeof (function () {
    log(123456)
})); // function
log(typeof Array); // function? 见第二点

// 举例
var str = "ilovecoding"
log(typeof str) // string
var newString = new String(str)
log(newString) // [String: 'ilovecoding']
log(typeof newString) // object
// 解释：当定义了一个str变量后，内存开辟了·栈·空间；
//      假设在内存中地址为ox123；new一个构造函数并生成实例化对象开辟了一个·堆·空间，且数据存储方式为key: value形式


// 2. instanceof返回的是bool值
//    ***** 检测A对象是否属于B对象实例化后出来的
//    ***** instanceof是顺着原型链检测的，在js中一切都基于Object(类似python的type和object类)
log([] instanceof Array); // true
log({} instanceof Object); // true
function Person() { };
log(new Person() instanceof Person); // true
log(new Date() instanceof Object); // true

// 举例
log(Object.prototype.toString.call(123)) // [object Number]
log(Object.prototype.toString.call([1, 2, 3])) // [object Array]
